<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>骨架屏</title>
</head>
<style>
    div.loading {
        border-radius: 5px;
        background-color: #efefef;
        color: transparent;
        border-color: transparent;
        overflow: hidden;
        position: relative;
    }
    @keyframes loadingFrame {
        0% {
            left: 0
        }
        100% {
            left: 100%;
        }
    }
    .loading:before {
        content: '';
        display: block;
        width: 20px;
        top: -50%;
        height: 200%;
        position: absolute;
        transform: rotate(30deg);
        background-color: rgba(125,125,125,0.6);
        animation: loadingFrame infinite 2s linear;
    }
    .box {
       background-color: aqua;
        margin: 10px 20px;
    }
</style>
<body>
<div id="app" v-cloak>

    <template v-if="listNodeMap.size">
        <div v-for="(item, index) in listNodeMap">
            <div :class="[{loading: !listNodeMap.get(index).state}]" class="box">
                {{listNodeMap.get(index).index}}
            </div>

        </div>
    </template>
</div>
</body>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>

<script>
    const {createApp, ref} = Vue;
    createApp({
        setup() {
            // 加载的节点
            const listNodeMap = ref(new Map())
            const init = () => {
                // 模拟100个节点
                for(let i = 0; i < 100; i++) {
                    listNodeMap.value.set(i, {
                        index: i,
                        state: false
                    })
                }
                setState()
            }

            // 计算节点修改次数
            let computedStateChange = 0;
            const setState = () => {
                if (computedStateChange < listNodeMap.value.size) {
                    listNodeMap.value.set(computedStateChange, {
                        index: computedStateChange,
                        state: true
                    })
                    computedStateChange++;
                    setTimeout(() => {
                        setState()
                    }, 100 * Math.random())

                }
            }
            init()
            return {
                listNodeMap
            }
        }
    }).mount('#app')
</script>

</html>
